package com.yydream.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yydream.common.constant.GlobalEnums;
import com.yydream.common.constant.HttpStatus;
import com.yydream.common.utils.PageUtils;
import com.yydream.common.utils.R;
import com.yydream.domain.LoginUser;
import com.yydream.dto.*;
import com.yydream.entity.SysRoleEntity;
import com.yydream.entity.SysRoleMenuEntity;
import com.yydream.entity.SysRoleUserEntity;
import com.yydream.entity.SysUserEntity;
import com.yydream.mapper.SysRoleMapper;
import com.yydream.mapper.SysUserMapper;
import com.yydream.service.*;
import com.yydream.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户表服务实现类
 * @author : yydream
 * @date : 2024-6-17
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUserEntity> implements SysUserService{


    @Autowired
    private SysRoleUserService sysRoleUserService;

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private SysRoleService sysRoleService;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    public R queryById(Long id){
        SysUserEntity sysUserEntity = this.getById(id);
        SysUserVo sysUserVo = new SysUserVo();
        BeanUtils.copyProperties(sysUserEntity, sysUserVo);
        return R.ok().put( sysUserVo);
    }

    /**
     * 新增数据
     *
     * @param sysUser 实例对象
     * @return 实例对象
     */
    @Transactional
    public R insert(SysUserDTO sysUser){
        String username = sysUser.getUsername();
        List<SysUserEntity> list = this.list(new LambdaQueryWrapper<SysUserEntity>().eq(SysUserEntity::getUsername, username));
        if (!CollectionUtil.isEmpty(list)) {
            return R.error(HttpStatus.USER_EXIST.getCode(), HttpStatus.USER_EXIST.getMsg());
        }
        String password = sysUser.getPassword();
        sysUser.setPassword(BCrypt.hashpw(password));
        SysUserEntity sysUserEntity = new SysUserEntity();
        BeanUtils.copyProperties(sysUser, sysUserEntity);
        this.save(sysUserEntity);
//        新增成功之后，需要默认关联角色
        SysRoleUserEntity sysRoleUserEntity = new SysRoleUserEntity();
        sysRoleUserEntity.setRoleId(GlobalEnums.NORMAL_ROLE.getCode());
        sysRoleUserEntity.setUserId(sysUserEntity.getId());
        sysRoleUserService.save(sysRoleUserEntity);
        return R.ok();
    }

    /**
     * 更新数据
     *
     * @param sysUser 实例对象
     * @return 实例对象
     */
    public R update(SysUserDTO sysUser){
        SysUserEntity sysUserEntity = this.getById(sysUser.getId());
        if (Objects.isNull(sysUserEntity)) {
            return R.error(HttpStatus.DATA_NOT_EXIST);
        }
        BeanUtils.copyProperties(sysUser, sysUserEntity);
        sysUserEntity.setUsername(null);
        if (!StringUtils.isEmpty(sysUser.getPassword())) {
            sysUserEntity.setPassword(BCrypt.hashpw(sysUser.getPassword()));
        }
        this.updateById(sysUserEntity);
        return R.ok();
    }

    /**
     * 通过主键删除数据
     *
     * @param ids 主键
     * @return 是否成功
     */
    public R deleteById(Long[] ids){
        List<SysUserEntity> userEntities = Arrays.stream(ids).map(c -> {
            SysUserEntity sysUserEntity = new SysUserEntity();
            sysUserEntity.setId(c);
            return sysUserEntity;
        }).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(userEntities)) {
            return R.error(HttpStatus.PARAM_ERROR);
        }
        boolean b = this.removeBatchByIds(userEntities);
        return R.ok().put( b);
    }

    @Override
    public R listPage(SysUserPageParamsDTO req) {
        List<SysUserPageVo> sysUserPageVos = this.baseMapper.customListPage(req);
        Paging<SysUserPageVo> customPageResult = PageUtils.getCustomPageResult(sysUserPageVos, req.getCurrPage(), req.getPageSize());
        setRoleInfo(customPageResult.getList());
        return R.ok().put( customPageResult);
    }

    public void setRoleInfo (List<SysUserPageVo> sysUserPageVos) {
        if (CollectionUtil.isNotEmpty(sysUserPageVos)) {
            List<Long> userIds = sysUserPageVos.stream().map(SysUserPageVo::getId).collect(Collectors.toList());
//        1. 通过 角色关联用户 中间表查询出来全部匹配的用户id信息
            List<SysRoleUserEntity> list = sysRoleUserService.list(new LambdaQueryWrapper<SysRoleUserEntity>().in(SysRoleUserEntity::getUserId, userIds));
//        2. 获取全部的角色id
            if (CollectionUtil.isNotEmpty(list)) {
                List<Long> roleIds = list.stream().map(SysRoleUserEntity::getRoleId).collect(Collectors.toList());
                // 3. 查询出来角色集合
                List<SysRoleEntity> roleEntityList = sysRoleService.list(new LambdaQueryWrapper<SysRoleEntity>().in(SysRoleEntity::getId, roleIds));
                if (CollectionUtil.isNotEmpty(roleEntityList)) {
                    sysUserPageVos.forEach(c -> {
                        List<SysRoleEntity> sysRoleEntities = new ArrayList<>();
                        Long userId = c.getId();
                        list.forEach(m -> {
                            if (m.getUserId().equals(userId)) {
                                roleEntityList.forEach(r -> {
                                    if (r.getId().equals(m.getRoleId())) {
                                        sysRoleEntities.add(r);
                                    }
                                });
                            }
                        });
                        c.setRoleList(sysRoleEntities);
                    });
                }
            }
        }
    }

    @Transactional
    @Override
    public R userRelationRole(UserRelationRoleDTO userRelationRoleDTO) {
        Long userId = userRelationRoleDTO.getUserId();
        List<SysUserEntity> list = this.list(new LambdaQueryWrapper<SysUserEntity>().eq(SysUserEntity::getId, userId));
        if (CollectionUtil.isEmpty(list)) {
            return R.error(HttpStatus.DATA_NOT_EXIST.getCode(), "用户ID： " + userId + " 不存在");
        }
        sysRoleUserService.remove(new LambdaQueryWrapper<SysRoleUserEntity>().eq(SysRoleUserEntity::getUserId, userId));
        List<Long> roleIds = userRelationRoleDTO.getRoleIds();
        if (CollectionUtil.isEmpty(roleIds)) {
            return R.ok().put( null);
        }
        List<SysRoleUserEntity> collect = roleIds.stream().map(c -> {
            SysRoleUserEntity entity = new SysRoleUserEntity();
            entity.setRoleId(c);
            entity.setUserId(userId);
            return entity;
        }).collect(Collectors.toList());
        boolean b = sysRoleUserService.saveBatch(collect);
        return R.ok().put( b);
    }

    @Override
    public R userRelationRoleByUserId(Integer userId) {
        List<SysRoleUserEntity> list = sysRoleUserService.list(new LambdaQueryWrapper<SysRoleUserEntity>()
                .eq(SysRoleUserEntity::getUserId, userId));
        if (CollectionUtil.isEmpty(list)) {
            return R.ok().put( null);
        }
        List<Long> roleIds = list.stream().map(SysRoleUserEntity::getRoleId).collect(Collectors.toList());
        return R.ok().put( roleIds);
    }

    @Override
    public R userInfo() {

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        LoginUser userDetails = (LoginUser) principal;
        // 1. 获取到用户id
        SysUserEntity userEntity = userDetails.getUserEntity();
        Long userId = userEntity.getId();
        SysUserEntity newUserEntity = this.getById(userId);
        if (Objects.isNull(newUserEntity)) {
            return R.error(HttpStatus.DATA_NOT_EXIST.getCode(), "账号不存在");
        }
        if (newUserEntity.getState() == 2) {
            return R.error(HttpStatus.INVALID_TOKEN.getCode(), "账号已被禁用");
        }
        SysUserInfoVo sysUserInfoVo = new SysUserInfoVo();
        BeanUtils.copyProperties(newUserEntity, sysUserInfoVo);
        // 2. 通过角色用户关联表查询有什么角色
        List<SysRoleUserEntity> list = sysRoleUserService.list(new LambdaQueryWrapper<SysRoleUserEntity>().eq(SysRoleUserEntity::getUserId, userId));
        if (!CollectionUtil.isEmpty(list)) {
            List<Long> roleIds = list.stream().map(SysRoleUserEntity::getRoleId).collect(Collectors.toList());
            // 3. 通过角色id集合，查询出来具体的角色信息
            List<SysRoleEntity> sysRoleEntities = sysRoleMapper.selectBatchIds(roleIds);
            if (!CollectionUtil.isEmpty(sysRoleEntities)) {
                List<SysRoleVo> sysRoleVos = PageUtils.toList(sysRoleEntities, SysRoleVo.class);
                sysUserInfoVo.setBelongRole(sysRoleVos);
                // 4. 通过角色关联菜单表查询菜单信息
                List<SysRoleMenuEntity> sysRoleMenuEntities = sysRoleMenuService.list(new LambdaQueryWrapper<SysRoleMenuEntity>().in(SysRoleMenuEntity::getRoleId, roleIds));
                if (!CollectionUtil.isEmpty(sysRoleMenuEntities)) {
                    // 5. 通过角色与菜单关联表查询出来的menuIds集合，查询出来具体的菜单
                    List<Long> menuIds = sysRoleMenuEntities.stream().map(SysRoleMenuEntity::getMenuId).collect(Collectors.toList());
                    List<SysMenuVo> menus = sysMenuService.queryByMenuIds(menuIds);
                    sysUserInfoVo.setMenuList(menus);
                }
            }
        }

        return R.ok().put( sysUserInfoVo);
    }
}